package com.lgCore.netty.server;

import com.lgCore.common.ProtocolCore;
import com.lgCore.netty.codec.handler.CommonRpcDecoderHandler;
import com.lgCore.netty.codec.handler.CommonRpcEncoderHandler;
import com.lgCore.netty.message.AskMsg;
import com.lgCore.netty.server.handler.NettyServerHandler;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.serialization.ClassResolvers;
import io.netty.handler.codec.serialization.ObjectDecoder;
import io.netty.handler.codec.serialization.ObjectEncoder;

import java.util.concurrent.TimeUnit;

public class NettyServerBootstrap {

	private int port;
	private EventLoopGroup boss;
	private EventLoopGroup worker;
    public NettyServerBootstrap(int port) throws InterruptedException {
        this.port = port;
        bind();
    }
 
    private void bind() throws InterruptedException {
        //通过硬件获取高效核心线程数
        int threadsNum = Runtime.getRuntime().availableProcessors() * 2;

        boss=new NioEventLoopGroup();
        worker=new NioEventLoopGroup();
        ServerBootstrap bootstrap=new ServerBootstrap();
        bootstrap.group(boss,worker);
        bootstrap.channel(NioServerSocketChannel.class);
        //服务器端接受连接的队列长度，如队列已满，那客户端连接被拒绝
        bootstrap.option(ChannelOption.SO_BACKLOG, 128);
        //通过NoDelay禁用Nagle,使消息立即发出去，不用等待到一定的数据量才发出去
        bootstrap.option(ChannelOption.TCP_NODELAY, true);
        //保持长连接状态
        bootstrap.childOption(ChannelOption.SO_KEEPALIVE, true);
        bootstrap.childHandler(new ChannelInitializer<SocketChannel>() {
            @Override
            protected void initChannel(SocketChannel socketChannel) throws Exception {
                ChannelPipeline p = socketChannel.pipeline();
//                p.addLast(new ObjectEncoder());
//                p.addLast(new ObjectDecoder(ClassResolvers.cacheDisabled(null)));


                p.addLast("decoder", new CommonRpcDecoderHandler());
                p.addLast("encoder", new CommonRpcEncoderHandler());


                p.addLast(new NettyServerHandler(threadsNum));
            }
        });
        ChannelFuture f= bootstrap.bind(port).sync();
        if(f.isSuccess()){
            System.out.println("-------------rpc server start---------------");
        }
    }
//    public static void main(String []args) throws InterruptedException {
//        ProtocolCore.kyroClass();
//        NettyServerBootstrap bootstrap=new NettyServerBootstrap(9999);
//        while (true){
//            SocketChannel channel=(SocketChannel)NettyChannelMap.get("101");
//            if(channel!=null){
//                AskMsg askMsg=new AskMsg();
//                channel.writeAndFlush(askMsg);
//            }
////            TimeUnit.SECONDS.sleep(5);
//        	//System.out.println(NettyChannelMap.getKeys());
//        	TimeUnit.SECONDS.sleep(15);
//        }
//    }

    public EventLoopGroup getBoss() {
        return boss;
    }

    public EventLoopGroup getWorker() {
        return worker;
    }

    public int getPort() {
        return port;
    }
}
